<template>
    <div class="video_wrap" ref="videoParentRef"></div>
</template>
<script setup>
import { getCurrentInstance, onMounted, onUnmounted, ref } from 'vue';
import { useRoute } from 'vue-router';
import { Config, PixelStreaming } from '@epicgames-ps/lib-pixelstreamingfrontend-ue5.3';
import { PixelStreamingApplicationStyle } from '@epicgames-ps/lib-pixelstreamingfrontend-ui-ue5.3';
const { proxy } = getCurrentInstance();
import { useStore } from '@/stores';
const route = useRoute();
const bus = proxy.$bus;
const store = useStore();

const videoParentRef = ref();
const stream = ref({});

onMounted(() => {
    //初始化视频流
    initPixelStream();

    // setUELog();//设置UE日志状态
    onSetSimulationMode();//设置当前场景
    onPutFire();//放置火源
    onPutFireDevice();//放置消防设施
    onSetRainLevel();//设置暴雨等级
    onPutFloodDevice();//放置排水设施
    onSetCognParams();//设置信息传播参数
    onStartSimulation();//开始模拟
    onChangeVillage();//切换小区
    onCancelSimCreation();//手动终止模拟
    onChangeWeather();//修改天气
    onCreateBookmark();//创建书签
    onGotoBookmark();//相机定位到书签
    onQueryBoorkmarks();
    onGetCameraInfo();//获取相机信息
    onSetCameraInfo();//设置相机
    onKeyboardInput();
    onChangeTime();
    onGetSpeed();
    onSetSpeed();
    onGetTime();
    onStopPlaying();//终止播放
    onEnableSection();//开始剖切
    onDisableSection();//停止剖切
    onDoDistanceMeasure();//开始或停止测量距离
    onDoAreaMeasure();//开始或停止测量面积
    onSetRoamScenario();//设置漫游场景
    onRoamPlay();//开始漫游
    onRoamPause();//暂停漫游
    onRoamReset();//重置漫游
});
onUnmounted(() => {
    bus.all.clear();
});

/**
 * 初始化UE视频流
 */
const initPixelStream = () => {
    const PixelStreamingApplicationStyles = new PixelStreamingApplicationStyle();
    PixelStreamingApplicationStyles.applyStyleSheet();
    const ss = import.meta.env.VITE_SS;
    const config = new Config({
        initialSettings: {
            AutoPlayVideo: true,
            AutoConnect: true,
            ss: ss,
            StartVideoMuted: true,
            WaitForStreamer: true,
            HoveringMouse: true,
            MouseInput: true,
        },
        // useUrlParams: true,
    });
    // Create a Native DOM delegate instance that implements the Delegate interface class
    stream.value = new PixelStreaming(config, { videoElementParent: videoParentRef.value });
    stream.value.addResponseEventListener("handle_responses", handleUEResponse);
    stream.value.addEventListener("webRtcConnected", webRtcConnected);
}

/**
 * 处理UE发送的数据
 * @param {*} response 
 */
const handleUEResponse = (response) => {
    // 收到的response为UE5发送的结构体
    const res = JSON.parse(response);
    // 根据收到的函数类型来进行操作与进一步的解析
    console.log(`${res.funcName}=====>`, res.args)
    switch (res.funcName) {
        case "simulationMode"://当前的模拟场景
            store.setMode(res.args.mode);
            setModeCN(res.args.mode);
            break;
        case "quitPlaceingStatus"://退出放置状态(火灾模拟放置火源后会触发)
            bus.emit("quitPlaceingStatus", null);
            break;
        case "playingStatus":
            //开始模拟后的播放状态,每秒发送一次
            if (res.args.isPlaying) {
                bus.emit("playingStatus", res.args);
                handlePlayingStatus(res.args);
            }
            break;
        case "simCreated":
            //模拟创建成功
            break;
        case "simCreationFailed":
            //模拟创建失败
            if (res.args && res.args.reason) {
                ElMessage({
                    showClose: true,
                    message: res.args.reason,
                    type: 'error',
                })
            }
            bus.emit("simCreationFailed", null);
            break;
        case "simProgress"://模拟进度条
            bus.emit("simProgress", res.args);
            break;
        case "simCanceled"://模拟被取消
            bus.emit("simCanceled", null);
            break;
        case "bookmarks": //书签列表
            bus.emit("bookmarks", res.args.bookmarks);
            break;
        case "cameraInfo"://相机信息
            store.setCameraInfo(res.args);
            break;
        case "speedInfo"://漫游速度
            bus.emit("speedInfo", res.args.speed);
            break;
        case "envTime"://当前时间
            bus.emit("envTime", res.args.time);
            break;
        case "mapInfo"://底图信息  湖口小区|宜盛花园|杏园小区
            store.setVillage(res.args.mapName);
            // store.setMode('car');
            // setMode('car');
            // setModeCN('car');
            break;
        default:
            console.log(`未识别的RespType: ${res.RespType}`);
    }
}
/**
 * 建立连接后
 */
function webRtcConnected() {
    console.log("===webRtcConnected===");
    setTimeout(() => {
        //获取底图信息
        emitUI("getMap");
        //获取当前的模拟预设状态
        emitUI("getSimulationMode")
        //如果url上携带了map参数,就切换地图
        setUEMapFromURL();
        //为了在刷新页面时,保持与UE服务器上剖切与测量功能协同,主动终止剖切与测量
        emitUI("disableSection");//终止剖切
        emitUI("doAreaMeasure", { "enable": false });//终止测量面积
        emitUI("doDistanceMeasure", { "enable": false });//终止测量距离
    }, 1000);
}
function setMode(mode) {
    emitUI("setSimulationMode", {
        "mode": mode
    })
}
function setModeCN(mode) {
    switch (mode) {
        case "car":
            store.setModeCN("人车模拟");
            break;
        case "fire":
            store.setModeCN("火灾模拟");
            break;
        case "water":
            store.setModeCN("地下空间内涝模拟");
            break;
        case "cogn":
            store.setModeCN("信息传播");
            break;
    }
}
/**
 * 根据小区名称切换小区
 */
function setUEMap(village) {
    if (village) {
        let mapName = ''
        if (village.indexOf('宜盛') == 0) {
            mapName = '宜盛花园'
        } else if (village.indexOf('湖口') == 0) {
            mapName = '湖口小区'
        } else if (village.indexOf('杏园') == 0) {
            mapName = '杏园小区'
        }
        emitUI("setMap", {
            mapName: mapName//可选的地图有宜盛花园、湖口小区、杏园小区
        });
        store.setVillage(village);
    } else {
        console.log("没有获取到小区信息");
    }
}
function setUEMapFromURL() {
    const mapName = route.query.map;
    if (mapName) {
        setUEMap(mapName);
    }
}
/**
 * 向UE发送请求
 * @param {*} funcName 方法名
 * @param {*} args  参数
 */
const emitUI = (funcName, args = {}) => {
    const params = {
        funcName: funcName,
        args: args,
    }
    console.log("emitUIInteraction=====>", params);
    stream.value.emitUIInteraction(params);
}
/**
 * 监听切换小区消息,收到消息后,向UE发送消息切换场景
 */
const onChangeVillage = () => {
    bus.on('changeVillage', (village) => {
        setUEMap(village);

    });
}
/**
 * 设置当前的模拟预设状态
 */
const onSetSimulationMode = () => {
    bus.on('setSimulationMode', (mode) => {
        setMode(mode);
        setModeCN(mode);
    });
}
/**
* 放置火源
*/
const onPutFire = () => {
    bus.on('putFire', (type) => {
        emitUI("putFire", {
            "type": type
        })
    });
}
/**
 * 放置消防设施
 */
const onPutFireDevice = () => {
    bus.on("putFireDevice", device => {
        emitUI("putFireDevice", {
            "type": device
        })
    })
}
/**
 * 设置暴雨等级
 */
const onSetRainLevel = () => {
    bus.on("setRainLevel", level => {
        emitUI("setRainLevel", {
            "type": level//1,2,3
        })
    })
}
/**
 * 放置排⽔设施
 */
const onPutFloodDevice = () => {
    bus.on("putFloodDevice", device => {
        emitUI("putFloodDevice", {
            "type": device//⽔泵部署 沙袋部署  ⽔位报警
        })
    })
}
/**
 * 设置信息传播参数
 */
const onSetCognParams = () => {
    bus.on("setCognParams", params => {
        emitUI("setCognParams", params);
    })
}
/**
 * 开始模拟
 */
const onStartSimulation = () => {
    bus.on('startSimulation', () => {
        emitUI("startSimulation");
    });
}

/**
 * 手动终止模拟
 */
const onCancelSimCreation = () => {
    bus.on("cancelSimCreation", () => {
        emitUI("cancelSimCreation");
    });
}
/**
 * 改变天气
 */
const onChangeWeather = () => {
    bus.on("changeWeather", (weather) => {
        emitUI("changeweather", {
            "weather": weather
        });
    });
}
/**
 * 创建书签
 */
const onCreateBookmark = () => {
    bus.on("createBookmark", () => {
        emitUI("createBookmark");
    });
}
/**
 * 查询书签
 */
const onQueryBoorkmarks = () => {
    bus.on("queryBoorkmarks", () => {
        emitUI("queryBookmarks")
    });
}
/**
 * 将相机定位到书签
 */
const onGotoBookmark = () => {
    bus.on("gotoBookmark", (id) => {
        emitUI("gotoBookmark", {
            'bookmark': id
        });
    });
}
/**
 * 获取当前的相机信息
 */
const onGetCameraInfo = () => {
    bus.on("getCameraInfo", () => {
        emitUI("getCameraInfo");
    });
}

/**
 * 设置相机信息
 */
const onSetCameraInfo = () => {
    bus.on("setCameraInfo", (params) => {
        // location[0,1,2]=x,y,z
        // rotation[0, 1, 2] = roll yaw pitch
        let args = {
            "location": [params['X'], params['Y'], params['Z']],
            "rotation": [params['Roll'], params['Yaw'], params['Pitch']]
        }
        emitUI("setCameraInfo", args);
    });
}
/**
 * 设置UE是否接收按键信息.
 */
const onKeyboardInput = () => {
    bus.on("keyboardInput", (flagEnabled) => {
        console.log("=====KeyboardInput=====", flagEnabled);
        // stream.value.config.setFlagEnabled("KeyboardInput", flagEnabled);
    });

}
/**
 * 获取当前漫游速度
 */
const onGetSpeed = () => {
    bus.on("getSpeed", () => {
        emitUI("getSpeed");
    });
}
/**
 * 设置漫游速度
 */
const onSetSpeed = () => {
    bus.on("setSpeed", (speed) => {
        emitUI("setSpeed", {
            speed: speed
        });
    });
}
/**
 * 获取时间
 */
const onGetTime = () => {
    bus.on("getTime", () => {
        emitUI("getTime");
    });
}
/**
 * 设置时间 time取值方式: 1100代表11:00，0530代表5:30，以此类推
 */
const onChangeTime = () => {
    bus.on("changeTime", (time) => {
        emitUI("changeTime", {
            time: time
        });
    });
}
/**
 * 终止播放
 */
const onStopPlaying = () => {
    bus.on("stopPlaying", () => {
        emitUI("stopPlaying");
    });
}
/**
 * 开始或停止测量距离
 */
const onDoDistanceMeasure = () => {
    bus.on("doDistanceMeasure", (enable) => {
        emitUI("doDistanceMeasure", {
            "enable": enable,//true | false
        });
    });
}
/**
 * 开始或停止测量面积
 */
const onDoAreaMeasure = () => {
    bus.on("doAreaMeasure", (enable) => {
        emitUI("doAreaMeasure", {
            "enable": enable,//true | false
        });
    });
}
/**
 * 开始剖切
 */
const onEnableSection = () => {
    bus.on("enableSection", () => {
        emitUI("enableSection");
    });
}
/**
 * 停止剖切
 */
const onDisableSection = () => {
    bus.on("disableSection", () => {
        emitUI("disableSection");
    });
}
/**
 * 设置漫游场景
 */
const onSetRoamScenario = () => {
    bus.on("setRoamScenario", (scenario) => {
        emitUI("setRoamScenario", {
            "scenario": scenario,//outdoor,室外漫游(小区道路)   indoor,室内漫游(居委会)   parking,地库漫游(地下车库)
        });
    });
}
/**
 * 开始漫游
 */
const onRoamPlay = () => {
    bus.on("roamPlay", () => {
        emitUI("roamPlay");
    });
}
/**
 * 暂停漫游
 */
const onRoamPause = () => {
    bus.on("roamPause", () => {
        emitUI("roamPause");
    });
}
/**
 * 重置漫游
 */
const onRoamReset = () => {
    bus.on("roamReset", () => {
        emitUI("roamReset");
    });
}
/**
 * 获取底图信息
 */
const onGetMap = () => {
    bus.on("getMap", () => {
        emitUI("getMap");
    });
}
/**
 * 模拟中
 * @param {*} args {"id": "fire_small26","isPlaying": true,"mode": "fire","step": 365}
 */
const handlePlayingStatus = (args) => {
    if (args['mode'] == 'car') {
        bus.emit("carPlaying", args);
    } else if (args['mode'] == 'fire') {
        bus.emit("firePlaying", args);
    } else if (args['mode'] == 'water') {
        bus.emit("floodPlaying", args);
    } else if (args['mode'] == 'cogn') {
        bus.emit("cognPlaying", args);
    }
}
</script>
<style scoped></style>